package com.pkche.core.advanced.util.image;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Iterator;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.spi.IIORegistry;
import javax.imageio.stream.ImageInputStream;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.log4j.Logger;

import com.pkche.core.advanced.util.MimeTypes;

import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.geometry.Positions;
//import net.sf.javavp8decoder.imageio.WebPImageReaderSpi;

/**
 * 图像处理，封装了诸如缩略图生成、水印、格式转换等API
 * 
 * @author yc
 *
 */
public class ImageUtil {
	private static final SimpleDateFormat sdf = new SimpleDateFormat("HHmmss");
	private static final Logger logger = Logger.getLogger(ImageUtil.class);
	private static Boolean include = false;

	// 最大允许下载2M以内的图像
	public final static int DOWNLOAD_IMG_MAX_LENGHT = 1024 * 1024 * 2;

	public enum IMAGE_FORMAT {
		BMP("bmp"), JPG("jpg"), WBMP("wbmp"), JPEG("jpg"), PNG("png"), GIF(
				"gif"), WEBP("webp");

		private String value;

		IMAGE_FORMAT(String value) {
			this.value = value;
		}

		public String getValue() {
			return value;
		}

		public void setValue(String value) {
			this.value = value;
		}
	}

	/**
	 * 获取以当前时间时分秒加四位随机数的图片名称
	 * 
	 * @return String
	 */
	public static String imageName() {
		Calendar cl = Calendar.getInstance();
		int max = 9999;
		int min = 1000;
		Random random = new Random();
		int s = random.nextInt(max) % (max - min + 1) + min;
		return sdf.format(cl.getTime()) + s;
	}

	/**
	 * 按比例通过指定像素大小缩放图片 若图片横比${width}小，高比${height}小，不变
	 * 若图片横比${width}小，高比${height}大，高缩小到${height}，图片比例不变
	 * 若图片横比${width}大，高比${height}小，横缩小到${width}，图片比例不变
	 * 若图片横比${width}大，高比${height}大，图片按比例缩小，横为${width}或高为${height}
	 * 
	 * @param sourceFile
	 * @param toFile
	 * @param width
	 * @param height
	 * @throws java.io.IOException
	 */
	public static void scale(String sourceFile, String toFile, int width,
			int height) throws IOException {

		String formatName = ImageUtil.getImageFormatName(new File(sourceFile));
		if (formatName == IMAGE_FORMAT.GIF.getValue()) {
			GifDecoder gd = new GifDecoder();
			int status = gd.read(new FileInputStream(new File(sourceFile)));
			if (status != GifDecoder.STATUS_OK) {
				return;
			}

			AnimatedGifEncoder ge = new AnimatedGifEncoder();
			ge.start(new FileOutputStream(new File(toFile)));
			ge.setRepeat(0);

			for (int i = 0; i < gd.getFrameCount(); i++) {
				BufferedImage frame = gd.getFrame(i);
				BufferedImage rescaled = Scalr.resize(frame,
						Scalr.Mode.FIT_EXACT, width,
						height);
				int delay = gd.getDelay(i);
				ge.setDelay(delay);
				ge.addFrame(rescaled);
			}
			ge.finish();
		} else {
			Thumbnails.of(sourceFile).size(width, height).outputQuality(1)
					.toFile(toFile);
		}

	}

	/**
	 * 为图片添加水印
	 * 
	 * @param sourceFile
	 * @param toFile
	 * @param logoImg
	 * @throws java.io.IOException
	 */
	public static void addLogo(String sourceFile, String toFile, String logoImg)
			throws IOException {
		// watermark(位置，水印图，透明度)
		Thumbnails
				.of(sourceFile)
				.watermark(Positions.BOTTOM_RIGHT,
						ImageIO.read(new File(logoImg)), 0.5f)
				.outputQuality(0.8f)
				.toFile("c:/a380_watermark_bottom_right.jpg");

	}

	/**
	 * 获取图片格式
	 * 
	 * @param file
	 *            图片文件
	 * @return 图片格式
	 */
	public static String getImageFormatName(File file) {
		String formatName = null;
		try {
			ImageInputStream iis = ImageIO.createImageInputStream(file);
			Iterator<ImageReader> imageReader = ImageIO.getImageReaders(iis);
			if (imageReader.hasNext()) {
				ImageReader reader = imageReader.next();
				formatName = reader.getFormatName();
			}
		} catch (IOException e) {
			logger.error("获取图片类型发生异常", e);
		}
		return formatName;
	}

	/**
	 * 转换为MimeType
	 * 
	 * @param type
	 * @return
	 */
	public static String getMimeType(String type) {
		if (type.equals(IMAGE_FORMAT.GIF)) {
			return MimeTypes.GIF.getValue();
		} else if (type.equals(IMAGE_FORMAT.JPEG.getValue())
				|| type.equals(IMAGE_FORMAT.JPG.getValue())) {
			return MimeTypes.JPEG.getValue();
		} else if (type.equals(IMAGE_FORMAT.PNG.getValue())) {
			return MimeTypes.PNG.getValue();
		} else if (type.equals(IMAGE_FORMAT.BMP.getValue())) {
			return MimeTypes.BMP.getValue();
		} else if (type.equals(IMAGE_FORMAT.WEBP.getValue())) {
			return MimeTypes.WEBP.getValue();
		}
		return MimeTypes.GIF.getValue();
	}

	/**
	 * 从给定的地址下载图片到本地
	 * 
	 * @param url
	 * @param localPath
	 * @return
	 */
	public static String downLoadImage(URL url, String localPath) {
		logger.debug("开始从给定URL下载图片" + url.toString());
		String fileName = imageName();
		String type = "jpg";
		DefaultHttpClient httpclient = new DefaultHttpClient();
		HttpGet httpget = new HttpGet(url.toString());
		httpget.setHeader(
				"User-Agent",
				"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/40.0.2214.115 Safari/537.36");
		httpget.setHeader("Accept",
				"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");

		try {
			HttpResponse resp = httpclient.execute(httpget);
			if (HttpStatus.SC_OK == resp.getStatusLine().getStatusCode()) {
				HttpEntity entity = resp.getEntity();
				InputStream in = entity.getContent();
				Header cType = resp.getFirstHeader("content-type");
				String imgtype = "jpg";
				if (cType != null) {
					imgtype = cType.getValue();
				} else {
					imgtype = URLConnection.guessContentTypeFromStream(in);
				}

				if (imgtype != null) {
					imgtype = imgtype.substring(imgtype.indexOf("/") + 1)
							.toLowerCase();
					imgtype = "jpeg".equals(imgtype) ? "jpg" : imgtype;
					fileName = fileName + "." + imgtype;
				} else {
					fileName = fileName + "." + type;
				}

				String locateFile=savePicToDisk(in, localPath, fileName);

				if ("webp".equals(imgtype)) {
					// webp形式的图像需要另外处理
					logger.debug("图像为webp格式，需要转换为jpg进行显示");
					imgtype = "jpg";
					ImageUtil.webpToJpg(
							localPath + File.separator + fileName,
							localPath + File.separator
									+ fileName.replace("webp", imgtype));
					fileName = fileName.replace("webp", imgtype);
				}

			}

		} catch (Exception e) {
			logger.error("图片下载失败", e);
		} finally {
			httpclient.getConnectionManager().shutdown();
		}
		return fileName;
	}

	/**
	 * 将图片写到 硬盘指定目录下
	 * 
	 * @param in
	 * @param dirPath
	 * @param filePath
	 */
	public static String savePicToDisk(InputStream in, String dirPath,
			String filePath) {

		try {
			File dir = new File(dirPath);
			if (dir == null || !dir.exists()) {
				dir.mkdirs();
			}

			// 文件真实路径
			String realPath = dirPath+File.separator+filePath;
			File file = new File(realPath);
			if (file == null || !file.exists()) {
				file.createNewFile();
			}

			FileOutputStream fos = new FileOutputStream(file);
			byte[] buf = new byte[1024];
			int len = 0;
			while ((len = in.read(buf)) != -1) {
				fos.write(buf, 0, len);
			}
			fos.flush();
			fos.close();

			return realPath;
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				in.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return null;
	}

	/**
	 * Webp格式图片转换为jpg图片格式
	 * 
	 * @param webpPath
	 * @param jpgPath
	 */
	public static void webpToJpg(String webpPath, String jpgPath) {
		
		 if(!include){
			 IIORegistry r = IIORegistry.getDefaultInstance(); 
			 //WebPImageReaderSpi s = new WebPImageReaderSpi();
			 //r.registerServiceProvider(s);
			 include = true; 
		 }
		 BufferedImage bi; 
		 try { 
			 bi = ImageIO.read(new File(webpPath));
			 ImageIO.write(bi, "jpg", new File(jpgPath));
			 } catch (IOException e)
			{ 
			 logger.info("webp转换jpg时发生异常,webpPath:" + webpPath);
			 // logger.error("webp转换为jpg时发生异常",e); 
			 }catch (Exception e) {
				 
			 }
		 
	}

	public static void main (String[] args) throws MalformedURLException {
		downLoadImage(
				new URL("http://mmbiz.qpic.cn/mmbiz/s1HUBEhA21Foia0LgBfKKHg5lvyZXGTmiaVWhqiaYSWiblMFZupsribN70ZPHVvrKQelpzhPaEOmSmiaSWeEtALTVVQw/0") ,
				"D:\\test");
	}


}
